package MetaClassifierAlgorithms;

import java.util.Arrays;

import Definitions.GraphClass;
import Global.GlobalClass;
import Sampling.SamplingAbstractClass;
import Utility.WorkerUtilityClass;

public class CorrNormalizedLocalAlphaBasedMetaClassifierClass extends MetaClassifierAbstractClass {

	CorrNormalizedLocalAlphaBasedMetaClassifierClass(String metaClassifierName,
			GraphClass graph, GlobalClass global,
			SamplingAbstractClass currentSampling,
			double[][][] probabilityDistributionMatrixForTheClassifiers) {
		super(metaClassifierName, graph, global, currentSampling,
				probabilityDistributionMatrixForTheClassifiers);
		// TODO Auto-generated constructor stub
	}
	
	public void metaClassify()
	{
		double sumOfTheWeightedProbabilitiesPerClassBasis[] = new double[global.classSize];
		//double metaResultProbabilitiesPerClassBasis[] = new double[GlobalClass.classSize];
		double[][] weightsToBeUsed = currentSampling.getLocalAlphaMatrixForThisFold();
		
		double[] correlationCoefficients = currentSampling.getCorrelationsBwLAandAccThisFold();
		//double[][] weightsToBeUsed = new double[weightsToBeUsedTemp.length][weightsToBeUsedTemp[0].length]; //= currentSampling.getLocalAlphaMatrixForThisFold();
		
		
		for(int i=0; i<correlationCoefficients.length; i++)
			if(correlationCoefficients[i]<0)
				correlationCoefficients[i] = 0;
				
		
		double[] globalWeightsToBeUsed = new double[weightsToBeUsed.length];		
		
		int metaClassLabelEstimated;
		
		double sumOfTheLocalAlphaWeigthsForTheNode;
		
		//WorkerUtilityClass.initializeTwoDimensionalArray(weightsToBeUsed, 5.0);
		
		for(int j=0; j<probabilityDistributionMatrixForTheClassifiers.length; j++)
			globalWeightsToBeUsed[j] = Utility.WorkerUtilityClass.getAverage(weightsToBeUsed[j]);
		
		
		int[] numberOfLocalAlphaUsagePerCls = new int[probabilityDistributionMatrixForTheClassifiers.length];
		int[] numberOfGlobalAlphaUsagePerCls = new int[probabilityDistributionMatrixForTheClassifiers.length];
		int[] sumMethodLikeUsagePerCls = new int[probabilityDistributionMatrixForTheClassifiers.length];
		
		for(int nodeNo=0; nodeNo<probabilityDistributionMatrixForTheClassifiers[0].length; nodeNo++)
		{
			Arrays.fill(sumOfTheWeightedProbabilitiesPerClassBasis,0.0);
						
			sumOfTheLocalAlphaWeigthsForTheNode = 0.0;
			
			for(int j=0; j<probabilityDistributionMatrixForTheClassifiers.length; j++)
				sumOfTheLocalAlphaWeigthsForTheNode += weightsToBeUsed[j][nodeNo];
			
			for(int j=0; j<probabilityDistributionMatrixForTheClassifiers.length; j++)
			{	
				//System.out.println("["+j+"]["+nodeNo+"]:"+weightsToBeUsed[j][nodeNo]);
				if(sumOfTheLocalAlphaWeigthsForTheNode!=0)
				{
					sumOfTheWeightedProbabilitiesPerClassBasis = WorkerUtilityClass.getVectoralSumOfTheDoubleArrays(sumOfTheWeightedProbabilitiesPerClassBasis, WorkerUtilityClass.getScalarProductOfTheArray(probabilityDistributionMatrixForTheClassifiers[j][nodeNo], weightsToBeUsed[j][nodeNo]*correlationCoefficients[j]));
					numberOfLocalAlphaUsagePerCls[j]++;
				}
				else if(globalWeightsToBeUsed[j]!=0)
				{
					sumOfTheWeightedProbabilitiesPerClassBasis = WorkerUtilityClass.getVectoralSumOfTheDoubleArrays(sumOfTheWeightedProbabilitiesPerClassBasis, WorkerUtilityClass.getScalarProductOfTheArray(probabilityDistributionMatrixForTheClassifiers[j][nodeNo], globalWeightsToBeUsed[j]*correlationCoefficients[j]));
					numberOfGlobalAlphaUsagePerCls[j]++;
				}
				else
				{
					sumOfTheWeightedProbabilitiesPerClassBasis = WorkerUtilityClass.getVectoralSumOfTheDoubleArrays(sumOfTheWeightedProbabilitiesPerClassBasis, probabilityDistributionMatrixForTheClassifiers[j][nodeNo]);
					sumMethodLikeUsagePerCls[j]++;
				}
			}
			//metaResultProbabilitiesPerClassBasis = WorkerUtilityClass.scalarDivisionOfTheArray(sumOfTheWeightedProbabilitiesPerClassBasis, probabilityDistributionMatrixForTheClassifiers[0].length);
			
			
			//metaClassLabelEstimated = WorkerUtilityClass.findMaxIndexForTheGivenVector(probabilityDistributionMatrixForTheClassifiers[1][nodeNo]);
			metaClassLabelEstimated = WorkerUtilityClass.findMaxIndexForTheGivenVector(sumOfTheWeightedProbabilitiesPerClassBasis);
			currentSampling.setClassLabelEstimated(currentSampling.getTestNodes().get(nodeNo), metaClassLabelEstimated);			
		}		
	
		WorkerUtilityClass.printArray(numberOfLocalAlphaUsagePerCls, "Local Alpha Usage Stats:");
		WorkerUtilityClass.printArray(numberOfGlobalAlphaUsagePerCls, "Global Alpha Usage Stats:");
		WorkerUtilityClass.printArray(sumMethodLikeUsagePerCls, "Sum Method like Usage Stats:");
	}


}
